/*
	Copyright (C) 2010 Salil Bhagurkar

	This file is part of k3

	k3 is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	k3 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with k3.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <shared.h>

/**
 * fs parsers
 */

extern struct fs root_fs;

/**
Find a link in the servers and clients of the fs node 'in'
*/
static struct fs *fsparse_find_link(struct fs *in, char *name)
{
	struct fs *t;
	int e = 0;
	t = in;
	fsiter_get_child(&t);
	while(!e) {
		if(!strcmp(t->name, name)) {
			return t;
		}
		e = fsiter_get_next(&t);
	}
	dprint(D_FREQ, "", "failed");
	return NULL;
}

/**
Parse a slash separated path name. A slash indicates a link which can either be a server or a client link.
 The find_link is then used to find the specified client or server.
 */
static struct fs *fsparse_path_name(struct fs *from, const char *s)
{
	static char path[MAX_FS_NAME_LEN];
	struct fs *n = from;
	u32 d=0;
	if(s[0]=='/') {
		n = &root_fs;
		d++;
	}
	while(1) {
		getstringparameter(s, path, '/', d);
		if(!strlen(path))
			break;
		if(!strcmp(path,".")) {}

		else if(!strcmp(path,".."))
			n = n->parent;
		else
			n = fsparse_find_link (n, path);
		if(!n)
			return NULL;
		d++;
	}
	return n;
}

/**
 * Get the fs node from the path string
 */
struct fs *fsparse_get(const char *s)
{
	return fsparse_path_name(&root_fs, s);
}

/**
 * Get the fs node from the path string relative to a specified node
 */
struct fs *fsparse_get_relative(struct fs *from, const char *s)
{
	return fsparse_path_name(from, s);
}


/*Generate a path name by tracing the parents of the fs node*/
static char *fsparse_generate_path_name(char *s, struct fs *node)
{
	if(node) {
		strcat(fsparse_generate_path_name(s, node->parent), node->name);
		strcat(s,"/");
		return s;
	} else
		return s;
}

/**
 * Same as above..I don't know why i wrote a wrapper
 */
char *fsparse_get_path(char *s, struct fs *node)
{
	return fsparse_generate_path_name(s, node);
}
